//
//  ZZGuidePageView.swift
//  KeDaLeDaoHang
//
//  Created by 陈钟 on 2019/6/3.
//  Copyright © 2019 陈钟. All rights reserved.
//

import UIKit

public struct ZZGuidePageModel {
    /// 高亮窗口
    public var showView: UIView!
    /// 显示文字
    public var text: String?
    /// 中心点 偏移量
    public var offset: CGPoint = CGPoint.zero
    /// 高亮大小
    public var lightSize: CGSize = CGSize.zero
    /// 自定义显示显示窗口  大小需要预先设置 在绘制时会自动修改 x,y
    public var customMsgView: UIView?
    
    public init(showView:UIView!, text:String?) {
        self.showView = showView
        self.text = text
    }
    
    public init(showView:UIView!, text:String?, offset:CGPoint) {
        self.showView = showView
        self.text = text
        self.offset = offset
    }
}

private var pageView: ZZGuidePageView? = nil

open class ZZGuidePageView: UIView {

    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */
    override public init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = RGB(r: 0, g: 0, b: 0, a: 0.5)
        self.createView()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.backgroundColor = RGB(r: 0, g: 0, b: 0, a: 0.5)
        self.createView()
    }
    
    public static func share() -> ZZGuidePageView{
        if pageView == nil {
            pageView = ZZGuidePageView.init()
        }
        return pageView!
    }
    
    open var selectIndex: Int = 0
    private var showGuides : [ZZGuidePageModel] = []
    private var showingCusMsgView: UIView?
    
    //MARK: - methods
    open func show(guide:ZZGuidePageModel) -> Void {
        self.showGuides.append(guide)
        self.addSelf()
    }
    open func show(guides:[ZZGuidePageModel]) -> Void {
        self.showGuides += guides
        self.addSelf()
    }
    open func addSelf() -> Void {
        self.frame = keyWindow?.bounds ?? CGRect.init(x: 0, y: 0, width: screen_width, height: screen_height)
        keyWindow?.addSubview(self)
    }

    @objc
    open func nextAction(){
        if self.selectIndex == (self.showGuides.count - 1) {
            self.showGuides.removeAll()
            self.selectIndex = 0
            self.removeFromSuperview()
            return;
        }
        self.selectIndex += 1
        self.setNeedsDisplay()
    }

    //MARK: - views
    open lazy var dottedLayer: CAShapeLayer = {
        let layer = CAShapeLayer.init()
        layer.lineWidth = 1
        layer.fillColor = nil
        layer.strokeColor = UIColor.white.cgColor
        layer.lineDashPattern = [4.0]
        layer.lineCap = .round
        self.layer.addSublayer(layer)
        return layer
    }()
    open lazy var messageLab: UILabel = {
        let label = UILabel.init()
        label.textColor = UIColor.white
        label.font = FontSize(size: 13)
        label.textAlignment = .center
        return label
    }()
    open lazy var nextButton: UIButton = {
        let button = UIButton.init()
        button.backgroundColor = UIColor.clear
        button.setImage(UIImage.named(name: "map_guidepage_iknow"), for: .normal)
        button.size = CGSize.init(width: 110, height: 47)
        button.addTarget(self, action: #selector(self.nextAction), for: .touchUpInside)
        return button
    }()
    open func createView() -> Void {
        self.addSubview(self.messageLab)
        self.addSubview(self.nextButton)
    }
    override open func layoutSubviews() {
        super.layoutSubviews()
        self.messageLab.frame = self.bounds
        self.nextButton.center = CGPoint.init(x: self.width / 2.0, y: self.height - 100.0 * screen_min_scale)
    }
    /// 绘制地自定义消息提示框 默认 左边  若左边不够  显示右边   右边不够上边  上边不够下边
    open func createCustomMsgView(radius:CGFloat,center:CGPoint) -> Void {
        if self.showingCusMsgView == nil { return }
        
        var origin = CGPoint.init(x: center.x - radius - 4 - (self.showingCusMsgView?.size.width ?? 0), y: center.y - 4 - (self.showingCusMsgView?.height ?? 0) / 2.0)
        if origin.x < 0 {
            origin.x = center.x + radius + 4
        }
        if (origin.x + (self.showingCusMsgView?.width ?? 0)) > self.width  {
            origin.x = (self.width - (self.showingCusMsgView?.width ?? 0)) / 2.0
        }
        
        if (origin.y < 0){
            origin.y = center.y + radius + 4
        }
        if (origin.y + (self.showingCusMsgView?.height ?? 0)) > self.height {
            origin.y = center.y - radius - 4 - (self.showingCusMsgView?.height ?? 0)
        }
        
        self.addSubview(self.showingCusMsgView!)
        self.showingCusMsgView?.origin = origin
        
    }
    
    override open func draw(_ rect: CGRect) {
        if self.showingCusMsgView != nil {
            self.showingCusMsgView?.removeFromSuperview()
        }
        guard let willShowModel = self.showGuides[self.selectIndex,true] else { return }
        self.messageLab.text = willShowModel.text
        self.showingCusMsgView = willShowModel.customMsgView
        guard let context = UIGraphicsGetCurrentContext() else{ return }
        let backgroundImage = context.makeImage()
        context.saveGState()
        
        context.translateBy(x: 0, y: rect.height)
        context.scaleBy(x: 1.0, y: -1.0)
        
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        
        let white:[CGFloat] = [1.0,1.0,1.0,1.0]
        let black:[CGFloat] = [0.0,0.0,0.0,0.8]
        let components:[CGFloat] = [white[0],white[1],white[2],white[3],
                                    black[0],black[1],black[2],black[3]]
//        let colorLocations:[CGFloat] = [0.25,0.4]
        let colorLocations:[CGFloat] = [1.0 ,1.0]
        guard let gradientRef = CGGradient.init(colorSpace: colorSpace,
                                                colorComponents: components,
                                                locations: colorLocations,
                                                count: 2) else { return }
        
        guard let window = UIApplication.shared.delegate?.window else { return }
        let showFrame = willShowModel.showView.bounds
        let converFrame = willShowModel.showView.convert(showFrame, to: window)
        let centerPoint = CGPoint.init(x: converFrame.x + converFrame.size.width / 2.0 + willShowModel.offset.x,
                                       y: converFrame.y + converFrame.size.height / 2.0 + willShowModel.offset.y)
        
//        let centerPoint = willShowModel.showView.center
        var viewSize = converFrame.size
        if willShowModel.lightSize != CGSize.zero {
            viewSize = willShowModel.lightSize
        }
        let radius = min(viewSize.width, viewSize.height) / 2.0
        
        context.drawRadialGradient(gradientRef,
                                   startCenter: centerPoint,
                                   startRadius: 0,
                                   endCenter: centerPoint,
                                   endRadius: radius,
                                   options: .drawsBeforeStartLocation)
        context.restoreGState()
        
        self.createCustomMsgView(radius: radius, center: centerPoint)
        
        let dottedpath = UIBezierPath.init(arcCenter: centerPoint, radius: radius + 4, startAngle: 0, endAngle: CGFloat(Double.pi * 2.0), clockwise: true)
        self.dottedLayer.path = dottedpath.cgPath
        
        
        guard let maskImage = context.makeImage() else { return }
        guard let mask = CGImage.init(maskWidth: maskImage.width,
                                height: maskImage.height,
                                bitsPerComponent: maskImage.bitsPerComponent,
                                bitsPerPixel: maskImage.bitsPerPixel,
                                bytesPerRow: maskImage.bytesPerRow,
                                provider: maskImage.dataProvider!,
                                decode: nil,
                                shouldInterpolate: false) else { return }
        guard let masked = backgroundImage?.masking(mask) else { return }
        
        context.clear(rect)
        context.draw(masked, in: rect)
    }
    
    override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super .touchesEnded(touches, with: event)
        self.nextAction()
    }
}
